package com.spring.wx.oauth.conntroller;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.spring.wx.oauth.entity.*;
import com.spring.wx.oauth.service.CompanyService;
import com.spring.wx.oauth.service.UserEmployeeSalaryRecordsService;
import com.spring.wx.oauth.service.UserService;
import com.spring.wx.oauth.service.VerifyCodeService;
import com.spring.wx.oauth.utils.HttpClientUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Objects;

@Controller
public class WXConntroller {

    @Autowired
    private UserService userService;

    @Autowired
    private VerifyCodeService verifyCodeService;

    @Autowired
    private UserEmployeeSalaryRecordsService salaryRecordsService;
    @Autowired
    private CompanyService companyService;

    @Value("${oauth.wx.appid}")
    private String appid;

    @Value("${oauth.wx.appsecret}")
    private String appsecret;

    @Value("${oauth.callback.http}")
    private String http;

    @GetMapping("/index")
    public String index() {
        return "/index";
    }

    @GetMapping("/wxlogin")
    public String wxlogin() {
        // 第一步：用户同意授权，获取code
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid +
                "&redirect_uri=" + http +
                "&response_type=code" +
                "&scope=snsapi_userinfo" +
                "&state=STATE#wechat_redirect";
        return "redirect:" + url;
    }

    @GetMapping("/wxcallback")
    public String wxcallback(String code, ModelMap map) throws IOException {
        // 第二步：通过code换取网页授权access_token
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid +
                "&secret=" + appsecret +
                "&code=" + code +
                "&grant_type=authorization_code";
        JSONObject jsonObject = HttpClientUtils.doGet(url);

        String openid = jsonObject.getString("openid");
        String access_Token = jsonObject.getString("access_token");

        System.out.println(jsonObject);

        // 第四步：拉取用户信息(需scope为 snsapi_userinfo)
        url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_Token +
                "&openid=" + openid +
                "&lang=zh_CN";
        JSONObject userInfoJson = HttpClientUtils.doGet(url);
        System.out.println("UserInfo:" + userInfoJson);

        // 1种情况, 是基于微信授权的账号做为我们本系统的账号体系来使用
        // map.put("userinfo", userInfoJson);
        // return "/home";


        // 2种情况: 我们是有账号体系的，微信帐号做来一个关联，来关联我们的账号体系
        UserEntity userEntity = userService.getOpenid(openid);
        if (userEntity == null) {
            userEntity = new UserEntity();
            userEntity.setType(0);
            userEntity.setOpenid(openid);
            userEntity.setNickname((String) userInfoJson.get("nickname"));
            userEntity.setImage((String) userInfoJson.get("headimgurl"));
            userService.insert(userEntity);
        } else {
            userEntity.setNickname((String) userInfoJson.get("nickname"));
            userEntity.setImage((String) userInfoJson.get("headimgurl"));
            userService.update(userEntity);
        }

        return "redirect:/gohome?openid=" + openid;
    }

    @GetMapping("/gohome")
    public String gohome(String openid, ModelMap map) {
        UserEntity userEntity = userService.getOpenid(openid);
        if (StringUtils.isEmpty(userEntity.getPhone()) || userEntity.getType()!=1) {
            return "redirect:/verifyer?openid=" + openid;
        } else {
            map.put("userEntity", userEntity);
            List<SalaryListData> saleryHrefList = getSalaryListDataList(userEntity.getPhone());
            map.put("saleryHrefList", saleryHrefList);
            return "/salary-list";
        }
    }

    @GetMapping("/getSalaryDetail")
    public String getSalaryDetail(Long id, ModelMap map) {
        SalaryData data = getData(id);
        if(Objects.isNull(data)){
            //撤回逻辑
            return "/recall";
        } else{
            map.put("salaryData", data);
            return "/salaryDetail";
        }
    }

    @GetMapping("/register")
    public String register(String openid, ModelMap map) {
        UserEntity userEntity = userService.getOpenid(openid);
        map.put("userEntity", userEntity);
        return "register";
    }

    //    @ResponseBody
    @GetMapping("/regsave")
    public String regsave(String openid, String verifyCode) {

        UserEntity userEntity = userService.getOpenid(openid);
        if (StringUtils.isEmpty(userEntity.getPhone())) {
            return "redirect:/verifyer?openid=" + openid;
        } else {
            //手机验证码校验
            boolean verifyCodeResult = verifyCode(userEntity.getPhone(), verifyCode);
            if (!verifyCodeResult) {
                return "redirect:/showErrorMessage?errorMessage=" + "verify code error";
            } else {
                this.userService.updateType(openid, 1);
                return "redirect:/gohome?openid=" + openid;
            }
        }

    }

    @GetMapping("/salary-list")
    public String showErrorMessage(String openid, ModelMap map) {
        return "/salary-list";
    }

    @GetMapping("/verifyer")
    public String verifyer(String openid, ModelMap map) {
        UserEntity userEntity = userService.getOpenid(openid);
        map.put("userEntity", userEntity);
        return "verifyer";
    }

    @GetMapping("/getVerifyCode")
    public String getVerifyCode(String phone, String email, String openid) throws IOException {
        //发验证码
        String url = "https://springboot-iw6e-1617418-1309602981.ap-shanghai.run.tcloudbase.com/smart-admin-api/session/getVerificationCode?mobilePhone=" + phone;
        JSONObject jsonObject = HttpClientUtils.doGet(url);
        if (jsonObject.getInteger("code").equals(1)) {
            this.userService.init(openid, phone, email, -1);
            return "redirect:/register?openid=" + openid;
        }

        return "redirect:/verifyer?openid=" + openid;
    }

    private SalaryData getData(long id) {
        EmployeeSalaryEntity entity = salaryRecordsService.getSlaryDetailById(id);
        SalaryData data = null;
        if(entity.getState() == 6) {
            //已撤回
        } else {
            //还原出dataItem
            JSONObject jsonObject = JSONObject.parseObject(entity.getSalary_items());
            SalaryImportData salaryImportData = JSONObject.toJavaObject(jsonObject, SalaryImportData.class);

            data = new SalaryData();
            data.setCompanyName(getCompanyName(entity.getUid()));

            DateFormat bf = new SimpleDateFormat("yyyy年MM月");
            String dateStr = bf.format(entity.getPay_date());
            data.setDate(dateStr);

            data.setSalay(entity.getPay_amount().toString());

            data.setSalaryItemList(salaryImportData.getSalaryData());
        }

        return data;
    }


    public boolean verifyCode(String mobilePhone, String verifyCode) {
        List<VerifyCodeEntity> entityList = verifyCodeService.getVerifyCodeEntityFromPhoneNumber(mobilePhone);
        try {
            if (entityList != null && entityList.size() > 0 && entityList.get(0).getVerify_code().equals(Long.valueOf(verifyCode))) {
                return true;
            }
        } catch (Exception e) {
            return false;
        }

        return false;
    }

    private String getCompanyName(long uid) {
        UserCompanyEntity companyEntity = companyService.getCompany(uid);
        if(Objects.isNull(companyEntity)) {
            return "[公司暂未设置]";
        }
        return companyEntity.getCompany_name();
    }

    private List<SalaryListData> getSalaryListDataList(String phone) {
        List<SalaryListData> dataList = Lists.newArrayList();

        List<EmployeeSalaryEntity> salaryEntityList = salaryRecordsService.getSlaryDataList(phone);

        for(EmployeeSalaryEntity entity: salaryEntityList) {
            DateFormat bf = new SimpleDateFormat("yyyy年MM月");
            String dateStr = bf.format(entity.getPay_date());
            long id = entity.getId();
            dataList.add(new SalaryListData("getSalaryDetail?id=" + id, dateStr + "-薪资"));
        }

        return dataList;
    }

}
